package com.mouse.magent.server.action;

import com.mouse.magent.common.net.TcpServer;
import com.mouse.magent.common.protocol.Command;
import com.mouse.magent.common.protocol.Header;
import com.mouse.magent.common.protocol.Message;
import com.mouse.magent.common.service.BaseAction;
import com.mouse.magent.common.util.JsonUtil;
import com.mouse.magent.common.util.NettyUtil;
import com.mouse.magent.common.util.PropUtil;
import com.mouse.magent.common.util.StringUtil;
import com.mouse.magent.server.constant.ServerConstant;
import com.mouse.magent.server.handler.RemoteProxyHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
public class ProxyConnectAction extends BaseAction {
    private static String secret;

    @Override
    public void handle(ChannelHandlerContext ctx, Message message) throws Exception {
        log.info("proxy connect");
        Header header = message.getHeader();
        Map dataMap = JsonUtil.toObject(header.getResult(), Map.class);
        String secret = (String) dataMap.get("secret");
        if (StringUtil.isBlank(secret) || !secret.trim().equals(this.secret)) {
            log.error("channelId:{} ip:{} secret:{} 密码错误", message.getHeader().getChannelId(),
                    NettyUtil.getRemoteIp(ctx), secret);
            message.setType(Command.PROXY_CLOSE);
            header.setResult("密码错误");
            ctx.writeAndFlush(message);
            return;
        }
        Integer port = (Integer) dataMap.get("port");
        TcpServer tcpServer = new TcpServer();
        try {
            tcpServer.bind(port, new ChannelInitializer() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    ServerConstant.getRemoteChannelGroup().add(channel);
                    channel.pipeline().addLast(new ByteArrayDecoder(),
                            new ByteArrayEncoder(), new RemoteProxyHandler(ctx));
                }
            });
            ServerConstant.getChannelRemoteMap().put(ctx.channel().id(), tcpServer.getChannel());
        } catch (Exception e) {
            log.error("channelId:{} ip:{} secret:{} 错误", message.getHeader().getChannelId(),
                    NettyUtil.getRemoteIp(ctx), secret);
            message.setType(Command.PROXY_CLOSE);
            header.setResult(e.getMessage());
            ctx.writeAndFlush(message);
        }
        header.setResult(null);
        ctx.writeAndFlush(message);
        log.info("Register success, start server on port: " + port);
    }


    static {
        String tempSecret = PropUtil.getValue("server.secret", "893656121");
        if (StringUtil.isNotBlank(tempSecret)) secret = tempSecret;
    }
}
